<template>
    <ul class="tl-upload-progress" :style="{maxHeight:typeof maxHeight=== 'number'?`${maxHeight}px`:maxHeight}">
        <li v-for="(item,index) in files_list" :key="item.id"
            class="tl-upload-progress__item" @click.stop.prevent="handleOpenViewer(item)"
            :class="{'cursor-pointer': isViewerPdf(item)}">
            <div class="content">
                <div class="left">
                    <tl-mimetype-icon :lazy="imageLazy" :scroll-container="scrollContainer"
                                      v-if="item.url" class="tl-mimetype-icon"
                                      :data-url="item.url" :src="item.url"
                                      fit="cover"/>
                    <tl-mimetype-icon :lazy="imageLazy" :scroll-container="scrollContainer"
                                      v-else class="tl-mimetype-icon"
                                      :mime-type="item.type"
                                      fit="cover"/>
                </div>
                <div class="right">
                    <div class="tl-upload-progress__name">{{ item.name }}</div>
                    <!--文件大小-->
                    <div class="tl-upload-progress__size">
                        <template v-if="['pause','exception'].includes(item.status)">
                            <span v-if="item.status === 'exception'">上传失败</span>
                            <span v-else>已暂停</span>
                            <el-button type="text" class="tl-upload-progress__retry" size="mini"
                                       @click="handleRetryUpload(item)">重新上传
                            </el-button>
                        </template>
                        <template
                            v-else-if="item.progress && item.progress.uploadStarted && !item.progress.uploadComplete">
                            <span>{{ item.progress.bytesUploaded | bytes_filter }}</span>
                            <span>/</span>
                            <span>{{ item.progress.bytesTotal | bytes_filter }}</span>
                        </template>
                        <template v-else-if="item.size>0">{{ item.size | bytes_filter }}</template>
                        <template v-else>未知大小</template>
                    </div>
                    <div class="tl-upload-progress__progress"
                         v-if="['uploading','exception','pause'].includes(item.status)">
                        <el-progress style="flex: 1" :percentage="item.percentage"
                                     :color="item.status | status_color_filter"
                                     :format="progressFormat"
                                     :strokeWidth="strokeWidth"
                                     :showText="showText"/>
                    </div>
                </div>
            </div>
            <div class="action" @click.stop.prevent="noop" v-if="item.isUploadError === true">
                <el-button type="text" icon="tl-action__icon tl-icon-cancel"
                           @click="handleDelete(item)"/>
            </div>
            <div class="action" @click.stop.prevent="noop" v-else-if="item.url">
                <slot name="default-action" :item="item">
                    <el-button type="text" @click="handleClickAction(item)"
                               v-if="showSingleAction"
                               :icon="[actionIcon,'tl-action__icon'].join(' ')"/>
                </slot>
                <slot name="action" :item="item"/>
            </div>
        </li>
        <li class="tl-upload-progress__item tl-upload-btn"
            @click.stop.prevent="noop" v-if="showUpload" :key="-1">
            <slot>
                <el-button type="text" icon="tl-icon-add_circle"
                           @click="handlerClickUpload">
                    <span>上传文件</span>
                </el-button>
            </slot>
        </li>
    </ul>
</template>

<script>
    import TlMimetypeIcon from '@components/tl-ui/mimetype-icon';
    import FileUpload from '@bixiao/ui/lib/utils/files-upload/uppy';
    import createUploadConf from './utils/config';
    import {Progress, Button} from 'element-ui';
    import bytes from '@bixiao/utils/lib/bytes';
    import qs from "qs";

    import {cloneDeep} from 'lodash'

    export default {
        name: "tl-upload-progress",
        filters: {
            bytes_filter(input) {
                if (typeof input === "number") return bytes(input);
                return input;
            },
            status_color_filter(input) {
                switch (input) {
                    case "exception":
                        return "#ef2205";
                    default:
                        return "#5FD556"
                }
            }
            // #5FD556
        },
        components: {
            [TlMimetypeIcon.name]: TlMimetypeIcon,
            [Progress.name]: Progress,
            [Button.name]: Button,
        },
        props: {
            // 是否使用OSS上传
            isOss: Boolean,
            scrollContainer: {
                type: String,
                default: ".tl-upload-progress"
            },
            imageLazy: {
                type: Boolean,
                default: false
            },
            showSingleAction: {
                type: Boolean,
                default: true
            },
            actionIcon: {
                type: String,
                default: "tl-icon-download"
            },
            list: {
                type: Array,
                default: () => []
            },
            strokeWidth: {
                type: Number,
                default: 3
            },
            showText: {
                type: Boolean,
                default: false
            },
            /**
             * 显示上传
             */
            showUpload: {
                type: Boolean,
                default: false
            },
            // 上传服务信息
            uploadOptions: {
                type: Object,
                default: () => {
                    return {}
                }
            },
            maxHeight: {
                type: [Number, String],
                default: 190
            },
        },
        data() {
            return {
                upload_list: [],
                upload_list_map: new Map(),
            }
        },
        computed: {
            files_list() {
                const list = this.list; // 上传成功的文件
                const _upload_list = this.upload_list;
                const upload_list_map = this.upload_list_map;
                let upload_list = [];
                for (let [k, val] of [...upload_list_map]) {
                    if (Array.isArray(val)) {
                        upload_list = upload_list.concat(val)
                    }
                }
                const files = upload_list.concat(list);
                return files.map(value => {
                    const {progress} = value;
                    let percentage = 0, bytesUploaded = 0, uploadStarted, status = 'success';
                    const uploadURL = value.uploadURL || value.url
                    let url = /^https?:\/\//.test(uploadURL) ? uploadURL : null
                    if (progress && Object.keys(progress).length > 0 && !url) {
                        percentage = progress.percentage;
                        bytesUploaded = progress.bytesUploaded;
                    } else if (url) {
                        percentage = 100;
                    }

                    if (typeof value.status === "string") {
                        switch (value.status) {
                            case "success":
                                status = "success"
                                break;
                            case "ready":
                            case "uploading":
                                status = value.status;
                                break;
                            case "fail":
                                status = "exception"
                                break;
                            case "pause":
                                status = "pause"
                                break;
                        }
                    } else {
                        if (value.isUploadError) {
                            status = "exception"
                        } else if (value.isUploadSuccess) {
                            status = "success"
                        } else if (value.isUploadStart) {
                            status = 'uploading'
                        }
                    }

                    return {
                        ...value,
                        url,
                        percentage,
                        bytesUploaded,
                        status
                    }
                });
            },
            upload_options() {
                const uploadOptions = this.uploadOptions;
                const def = {
                    server: "/rich-text-upload",
                    maxSize: "10MB",
                    minSize: 1,
                    maxLength: 10,
                    minLength: 1,
                    params: {},
                    headers: {}
                }
                return {
                    ...def,
                    ...uploadOptions
                }
            }
        },
        methods: {
            isViewerPdf({type, url}) {
                return type === 'application/pdf' || /\.pdf$/i.test(url);
            },
            // 进度文字过滤
            progressFormat(percentage) {
                // if (this.progress.status === 'exception') return '上传失败';
                // return percentage === 100 ? '上传成功' : `${percentage}%`;
                return `${percentage}%`
            },
            // 重新上传
            handleRetryUpload(item) {
                if (this.showUpload && item.instance && item.instance) {
                    item.instance && item.instance.retryUpload(item.id);
                    item.status = ""
                    item.isUploadError = false
                } else {
                    this.$emit('retry-upload', item.id, item)
                }
            },
            handleDelete(item) {
                item && item.instance && item.instance.removeFile(item.id);
            },
            handleClickAction(item) {
                this.$emit('click-action', item.id, item)
            },
            // 点击上传
            handlerClickUpload() {
                if (this.isOss) return this.$emit('oss-upload-click');
                if (!this.fileUpload) this.createFileUpload();
                this.fileUpload.click();
            },
            createFileUpload() {
                if (this.fileUpload) this.destroy();
                const conf = createUploadConf(this.upload_options);
                const fileUpload = this.fileUpload = new FileUpload(this, {
                    ...conf,
                    events: {
                        complete: (result) => {
                            // 是否将图片追加进入html(富文本中)
                            let flag = true,
                                successLen = result.successful.length,
                                failedLen = result.failed.length;
                            let list = [];
                            if (successLen > 0) {
                                for (let value of result.successful) {
                                    const result = value.response.body || {};
                                    if (result.code === 0) {
                                        value.resultSuccess && list.push(cloneDeep(value.resultSuccess));
                                        fileUpload.removeFile(value.id);
                                    } else {
                                        failedLen++;
                                    }
                                }
                            }
                            list.length > 0 && this.$emit('files-complete', list)
                        },
                        ["file-change"]: this.addFiles
                    }
                })
            },
            addFiles(files, instance) {
                if (!Array.isArray(files)) return;
                files = files.filter(value => value.id)
                    .map(value => {
                        value.instance = instance;
                        return value
                    });
                let id = "other";
                if (typeof instance === "string") {
                    id = instance;
                } else if (instance && instance.getID) {
                    id = instance.getID();
                }
                if (id === "other") {
                    const otherFiles = this.upload_list_map.get(id);
                    if (Array.isArray(otherFiles)) {
                        const filesIDs = files.map(value => value.id)
                        const fileList = otherFiles.filter(value => !filesIDs.included(value.id))
                        files = files.concat(fileList);
                    }
                }
                this.upload_list_map.set(id, files);
                this.upload_list.push(files);
            },
            destroy() {
                this.fileUpload && this.fileUpload.destroy()
                this.fileUpload = null;
            },
            handleOpenViewer(item) {
                if (!item.url) return;
                if (this.isViewerPdf(item)) {
                    const query = qs.stringify({file: item.url})
                    window.open(`https://res.tuoluocard.com/bixiao-web-static/web/pdf/generic/web/viewer.html?${query}`, '_blank')
                }
            }
        }
    }
</script>

<style scoped lang="scss">
    .tl-upload-progress {
        margin-bottom: 0;
        overflow: auto;
        /*修改滚动条样式*/
        &::-webkit-scrollbar {
            width: 3px;
            height: 3px;
        }
    }

    .tl-upload-progress__item {
        display: flex;
        border-radius: 4px;
        border: 1px solid #F1F1F1;
        padding: 11px 0;
        justify-content: space-between;
        align-items: center;

        + .tl-upload-progress__item {
            margin-top: 6px;
        }

        .content {
            display: flex;
            flex: 1;
            align-items: center;
            padding-right: 10px;

            .left {
                padding: 0 8px;
                margin: 0;
                display: flex;
                align-items: center;

                .tl-mimetype-icon {
                    width: 34px;
                    height: 34px;

                    &.tl-mimetype-img {
                        padding: 3px;

                        ::v-deep {
                            > .tl-image__inner {
                                border-radius: 2px;
                            }
                        }
                    }

                }
            }

            .right {
                flex: 1;
            }
        }

        .action {
            padding: 0 9px;
            display: flex;
            align-items: center;

            .el-button--text {
                font-size: 20px;
                color: #969FAB;
                padding: 0 0;

                &:hover {
                    color: #0075ff;
                }

                ::v-deep {
                    line-height: 0;
                    position: relative;

                    i {
                        display: inline-block;

                        &.tl-action__icon.tl-icon-cancel {
                            width: 20px;
                            height: 20px;

                            &:before {
                                position: absolute;
                                font-size: 12px;
                                top: 50%;
                                left: 50%;
                                transform: translate(-50%, -50%);
                            }
                        }
                    }
                }
            }
        }

        .tl-upload-progress__name {
            font-size: 12px;
            font-weight: 400;
            color: #1F2329;
            line-height: 14px;
            display: -webkit-box;
            word-break: break-all;
            overflow: hidden;
            text-overflow: ellipsis;
            max-height: 28px;
            line-height: 14px;
            -webkit-line-clamp: 2;
        }

        .tl-upload-progress__size {
            font-size: 12px;
            font-weight: 400;
            color: #A2A8A8;
            line-height: 14px;
            margin-top: 5px;
            display: flex;
            align-items: center;
        }

        .tl-upload-progress__progress {
            margin-top: 3px;
        }

        .tl-upload-progress__retry {
            margin-left: 5px;
            padding: 0 0;
        }

        &.tl-upload-btn {
            padding-left: 14px;
            padding-right: 14px;
            height: 45px;
            cursor: pointer;

            ::v-deep {
                .el-button {
                    padding: 0;
                    font-weight: 400;
                    line-height: 1;

                    i {
                        font-size: 14px;
                        margin-right: 4px;
                    }
                }
            }
        }
    }
</style>
